﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DocumentServiceTests.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the DocumentServiceTests type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using ClientProxies;
using ClientProxies.OneStepServiceReference;
using Common.Contracts;

namespace ServiceTests
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using BusinessEngineInterfaces;
  using ClientProxies.ArchiveServiceReference;
  using Entities;
  using Exceptions;
  using FluentAssertions;
  using Moq;
  using NUnit.Framework;
  using ServiceInterfaces;
  using Services;
  using UnityRepository.Interfaces;

  [TestFixture]
  public class DocumentServiceTests
  {
    private static readonly String[] DocIds =
    {
      "f747c13e-b341-4b80-beed-ae08f52c0b3c",
      "d3d3f307-ccc4-4044-9c36-20ce347ee28d",
      "c3f85d02-76a8-4c8c-be34-4d8fc18d3174"
    };

    private Mock<IServiceFactory> _archiveServiceFactory;

    private Mock<IDocumentRepository> _documentRepository;

    private Mock<IIndexNameCriteraService> _indexNameCriteraService;

    private Mock<ISearchEngine> _documentEngine;

    private Mock<IDocTypeRepository> _docTypeRepository;

    private Mock<ISubDocTypeRepository> subDocTypeRepository;

    private Mock<IManCoRepository> _manCoRepository;

    private Mock<IHouseHoldRepository> houseHoldRepository;

    private IDocumentService _documentService;

    private PagedResult<IndexedDocumentData> _pagedDocuments;

    private DocumentSearchResultsData _documentSearchResultsData;

    private Mock<IDocument> _archiveServiceProxy;

    [SetUp]
    public void SetUp()
    {
      this._archiveServiceFactory = new Mock<IServiceFactory>();
      this._documentRepository = new Mock<IDocumentRepository>();
      this._indexNameCriteraService = new Mock<IIndexNameCriteraService>();
      this._documentEngine = new Mock<ISearchEngine>();
      this._docTypeRepository = new Mock<IDocTypeRepository>();
      this.subDocTypeRepository = new Mock<ISubDocTypeRepository>();
      this._manCoRepository = new Mock<IManCoRepository>();
      this.houseHoldRepository = new Mock<IHouseHoldRepository>();
      this._archiveServiceProxy = new Mock<IDocument>();

      this._documentService = new DocumentService(
        this._archiveServiceFactory.Object,
        this._documentRepository.Object,
        this._indexNameCriteraService.Object,
        this._documentEngine.Object,
        this._docTypeRepository.Object,
        this.subDocTypeRepository.Object,
        this._manCoRepository.Object,
        this.houseHoldRepository.Object);

      this._documentSearchResultsData = new DocumentSearchResultsData
                                        {
                                          DocumentList =
                                            new List<IndexedDocumentData>
                                            {
                                              new IndexedDocumentData
                                              {
                                                ApplicationCode
                                                  =
                                                  "NTGENXX",
                                                Id
                                                  =
                                                  new Guid
                                                  (
                                                  DocIds
                                                  [
                                                    0
                                                  ]),
                                                MappedIndexes
                                                  =
                                                  new List
                                                  <
                                                  IndexMapped
                                                  >
                                                  {
                                                    new IndexMapped
                                                    {
                                                      IndexName
                                                        =
                                                        "DocumentType",
                                                      IndexValue
                                                        =
                                                        "Document Type Value"
                                                    },
                                                    new IndexMapped
                                                    {
                                                      IndexName
                                                        =
                                                        "DocumentSubType",
                                                      IndexValue
                                                        =
                                                        "Document SubType Value"
                                                    }
                                                  }
                                              },
                                              new IndexedDocumentData
                                              {
                                                ApplicationCode
                                                  =
                                                  "NTGENXX",
                                                Id
                                                  =
                                                  new Guid
                                                  (
                                                  DocIds
                                                  [
                                                    1
                                                  ]),
                                                MappedIndexes
                                                  =
                                                  new List
                                                  <
                                                  IndexMapped
                                                  >
                                                  {
                                                    new IndexMapped
                                                    {
                                                      IndexName
                                                        =
                                                        "DocumentType2",
                                                      IndexValue
                                                        =
                                                        "Document Type Value2"
                                                    },
                                                    new IndexMapped
                                                    {
                                                      IndexName
                                                        =
                                                        "DocumentSubType2",
                                                      IndexValue
                                                        =
                                                        "Document SubType Value2"
                                                    }
                                                  }
                                              },
                                              new IndexedDocumentData
                                              {
                                                ApplicationCode
                                                  =
                                                  "NTGENXX",
                                                Id
                                                  =
                                                  new Guid
                                                  (
                                                  DocIds
                                                  [
                                                    2
                                                  ]),
                                                MappedIndexes
                                                  =
                                                  new List
                                                  <
                                                  IndexMapped
                                                  >
                                                  {
                                                    new IndexMapped
                                                    {
                                                      IndexName
                                                        =
                                                        "DocumentType3",
                                                      IndexValue
                                                        =
                                                        "Document Type Value3"
                                                    },
                                                    new IndexMapped
                                                    {
                                                      IndexName
                                                        =
                                                        "DocumentSubType3",
                                                      IndexValue
                                                        =
                                                        "Document SubType Value3"
                                                    }
                                                  }
                                              }
                                            }
                                        };

      this._archiveServiceFactory.Setup(x => x.CreateDocumentServiceClient<IDocument>())
        .Returns(_archiveServiceProxy.Object);

      _archiveServiceProxy.Setup(
        d =>
          d.DocumentSearch(
            It.IsAny<AuthenticationData>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<Int32>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>(),
            It.IsAny<String>())).Returns(this._documentSearchResultsData);

      this._pagedDocuments = new PagedResult<IndexedDocumentData>
                             {
                               CurrentPage = 1,
                               EndRow = 10,
                               StartRow = 1,
                               ItemsPerPage = 10,
                               Results =
                                 new List<IndexedDocumentData>
                                 {
                                   new IndexedDocumentData
                                   {
                                     ApplicationCode
                                       =
                                       "NTGENXX",
                                     Id
                                       =
                                       new Guid
                                       (
                                       DocIds
                                       [
                                         0
                                       ]),
                                     MappedIndexes
                                       =
                                       new List
                                       <
                                       IndexMapped
                                       >
                                       {
                                         new IndexMapped
                                         {
                                           IndexName
                                             =
                                             "DocumentType",
                                           IndexValue
                                             =
                                             "Document Type Value"
                                         },
                                         new IndexMapped
                                         {
                                           IndexName
                                             =
                                             "DocumentSubType",
                                           IndexValue
                                             =
                                             "Document SubType Value"
                                         }
                                       }
                                   },
                                   new IndexedDocumentData
                                   {
                                     ApplicationCode
                                       =
                                       "NTGENXX",
                                     Id
                                       =
                                       new Guid
                                       (
                                       DocIds
                                       [
                                         1
                                       ]),
                                     MappedIndexes
                                       =
                                       new List
                                       <
                                       IndexMapped
                                       >
                                       {
                                         new IndexMapped
                                         {
                                           IndexName
                                             =
                                             "DocumentType2",
                                           IndexValue
                                             =
                                             "Document Type Value2"
                                         },
                                         new IndexMapped
                                         {
                                           IndexName
                                             =
                                             "DocumentSubType2",
                                           IndexValue
                                             =
                                             "Document SubType Value2"
                                         }
                                       }
                                   }
                                 }
                             };
    }

    [Test]
    public void GivenAValidGrid_WhenISearchForDocuments_DocumentsAreReturned()
    {
      this._archiveServiceFactory.Setup(x => x.CreateDocumentServiceClient<IDocument>()).Returns(new DocumentClient());

      this._documentEngine.Setup(
        d =>
          d.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            false)).Returns(this._pagedDocuments);

      PagedResult<IndexedDocumentData> documents = this._documentService.GetDocuments(
        It.IsAny<Int32>(),
        It.IsAny<Int32>(),
        "grid",
        false,
        false,
        false);
      documents.Results.Should().HaveCount(2);

      documents.Results[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentType");
      documents.Results[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentSubType");
      documents.Results[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document Type Value");
      documents.Results[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document SubType Value");

      documents.Results[1].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentType2");
      documents.Results[1].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentSubType2");
      documents.Results[1].MappedIndexes.Should().Contain(d => d.IndexValue == "Document Type Value2");
      documents.Results[1].MappedIndexes.Should().Contain(d => d.IndexValue == "Document SubType Value2");
    }

    [Test]
    public void GivenAValidGrid_WhenISearchForDocuments_AndFilteringIsRequested_DocumentsAreReturned()
    {
      this._archiveServiceFactory.Setup(x => x.CreateDocumentServiceClient<IDocument>()).Returns(new DocumentClient());

      this._documentEngine.Setup(
        d =>
          d.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            true)).Returns(this._pagedDocuments);

      this._documentRepository.Setup(
        dr => dr.GetDocumentsIncludingApprovalRejectionAndHouseHoldEntities(It.IsAny<String>()))
        .Returns(
          new List<Document>
          {
            new Document { DocumentId = DocIds[0] },
            new Document { DocumentId = DocIds[1] },
            new Document { DocumentId = DocIds[2] }
          });

      PagedResult<IndexedDocumentData> documents = this._documentService.GetDocuments(
        It.IsAny<Int32>(),
        It.IsAny<Int32>(),
        "grid",
        true,
        true,
        true);

      this._documentRepository.Verify(
        d => d.GetDocumentsIncludingApprovalRejectionAndHouseHoldEntities(It.IsAny<String>()),
        Times.Once);

      documents.Results.Should().HaveCount(2);
    }

    [Test]
    public void GivenAValidGrid_WhenISearchForDocuments_AndIFilterByHouseHeld_HouseHeldDocumentsAreReturned()
    {
      this._documentRepository.Setup(
        dr => dr.GetDocumentsIncludingApprovalRejectionAndHouseHoldEntities(It.IsAny<String>()))
        .Returns(
          new List<Document>
          {
            new Document { DocumentId = DocIds[0] },
            new Document { DocumentId = DocIds[1], HouseHold = new HouseHold() },
            new Document { DocumentId = DocIds[2] }
          });

      DocumentSearchResultsData resultsData = null;
      this._documentEngine.Setup(
        de =>
          de.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            It.IsAny<Boolean>()))
        .Callback<Int32, Int32, Int32, Int32, DocumentSearchResultsData, Boolean>(
          (i1, i2, i3, i4, documentSearchResultsData, b1) => resultsData = documentSearchResultsData);

      this._documentService.GetDocuments(It.IsAny<Int32>(), It.IsAny<Int32>(), "grid", true, false, false);

      this._documentEngine.Verify(
        de =>
          de.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            It.IsAny<Boolean>()),
        Times.Once);

      resultsData.DocumentList.Should().HaveCount(1);

      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentType2");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentSubType2");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document Type Value2");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document SubType Value2");
    }

    [Test]
    public void
      GivenAValidGrid_WhenISearchForDocuments_AndIFilterByApprovedAndRejected_ApprovedAndRejectedDocumentsAreRemoved()
    {
      this._documentRepository.Setup(d => d.GetDocumentsIncludingApprovalRejectionAndHouseHoldEntities("grid"))
        .Returns(
          new List<Document>
          {
            new Document { DocumentId = DocIds[0], Approval = new Approval() },
            new Document { DocumentId = DocIds[1] },
            new Document { DocumentId = DocIds[2], Rejection = new Rejection() }
          });

      DocumentSearchResultsData resultsData = null;
      this._documentEngine.Setup(
        de =>
          de.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            It.IsAny<Boolean>()))
        .Callback<Int32, Int32, Int32, Int32, DocumentSearchResultsData, Boolean>(
          (i1, i2, i3, i4, documentSearchResultsData, b1) => resultsData = documentSearchResultsData);

      this._documentService.GetDocuments(It.IsAny<Int32>(), It.IsAny<Int32>(), "grid", false, false, true);

      this._documentEngine.Verify(
        de =>
          de.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            It.IsAny<Boolean>()),
        Times.Once);

      resultsData.DocumentList.Should().HaveCount(1);

      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentType2");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentSubType2");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document Type Value2");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document SubType Value2");
    }

    [Test]
    public void GivenAValidGrid_WhenISearchForDocuments_AndIFilterByUnApproved_ApprovedDocumentsAreRemoved()
    {
      this._documentRepository.Setup(d => d.GetDocumentsIncludingApprovalRejectionAndHouseHoldEntities("grid"))
        .Returns(
          new List<Document>
          {
            new Document { DocumentId = DocIds[0], Approval = new Approval() },
            new Document { DocumentId = DocIds[1] },
            new Document { DocumentId = DocIds[2], Rejection = new Rejection() }
          });

      DocumentSearchResultsData resultsData = null;
      this._documentEngine.Setup(
        de =>
          de.GetPagedResults(
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<Int32>(),
            It.IsAny<DocumentSearchResultsData>(),
            It.IsAny<Boolean>()))
        .Callback<Int32, Int32, Int32, Int32, DocumentSearchResultsData, Boolean>(
          (i1, i2, i3, i4, documentSearchResultsData, b1) => resultsData = documentSearchResultsData);

      this._documentService.GetDocuments(It.IsAny<Int32>(), It.IsAny<Int32>(), "grid", false, true, false);

      resultsData.DocumentList.Should().HaveCount(1);

      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentType");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexName == "DocumentSubType");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document Type Value");
      resultsData.DocumentList[0].MappedIndexes.Should().Contain(d => d.IndexValue == "Document SubType Value");
    }

    [Test]
    public void
      GivenAValidGrid_WhenISearchForDocuments_AndTheArchiveWebServiceIsNotAvailable_ThenAUnityExceptionIsThrown()
    {
      _archiveServiceProxy.Setup(
        d =>
          d.DocumentSearch(
            It.IsAny<AuthenticationData>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<int>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<string>())).Throws<Exception>();

      Action act =
        () =>
          _documentService.GetDocuments(
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<string>(),
            It.IsAny<bool>(),
            It.IsAny<bool>(),
            It.IsAny<bool>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenValidSearchCriteria_WhenISearchForDocuments_ThenDocumentsAreReturned()
    {
      var returnData = new DocumentSearchResultsIndexedData { DocumentList = new List<IndexedDocumentData>() };

      _archiveServiceProxy.Setup(
        d =>
          d.DocumentSearchMapVerbose(
            It.IsAny<AuthenticationData>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<DateTime?>(),
            It.IsAny<DateTime?>(),
            It.IsAny<List<IndexNameCriteriaData>>())).Returns(returnData);

      _documentEngine.Setup(
        d =>
          d.GetPagedResults(
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<DocumentSearchResultsIndexedData>())).Returns(_pagedDocuments);

      var listManCoTexts = new List<string>();
      listManCoTexts.Add("manco1");
      listManCoTexts.Add("manco2");

      var documents = _documentService.GetDocuments(
        1,
        10,
        "doctype",
        "subdoctype",
        "addresseeSubType",
        "accountNumber",
        "mailingName",
        listManCoTexts,
        "investorRef",
        new DateTime(2014, 1, 13, 13, 10, 22),
        new DateTime(2014, 1, 14, 13, 10, 22),
        "primaryHolder",
        "agentReference",
        "addressPoseCode",
        "emailAddress",
        "faxNumber",
        new DateTime(2014, 1, 13, 13, 10, 22),
        new DateTime(2014, 1, 12, 13, 10, 22),
        "documentNumber");
      documents.Should().NotBeNull();
    }

    [Test]
    public void GivenValidSearchCriteria_WhenISearchForDocuments_AndTheWCFServiceIsUnavailable_ThenDocumentsAreReturned(
      )
    {
      _archiveServiceProxy.Setup(
        d =>
          d.DocumentSearchMapVerbose(
            It.IsAny<AuthenticationData>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<int>(),
            It.IsAny<DateTime?>(),
            It.IsAny<DateTime?>(),
            It.IsAny<List<IndexNameCriteriaData>>())).Throws<Exception>();

      var listManCoTexts = new List<string>();
      listManCoTexts.Add("manco1");
      listManCoTexts.Add("manco2");

      Action act =
        () =>
          _documentService.GetDocuments(
            1,
            10,
            "doctype",
            "subdoctype",
            "addresseeSubType",
            "accountNumber",
            "mailingName",
            listManCoTexts,
            "investorRef",
            new DateTime(2014, 1, 13, 13, 10, 22),
            new DateTime(2014, 1, 14, 13, 10, 22),
            "primaryHolder",
            "agentReference",
            "addressPoseCode",
            "emailAddress",
            "faxNumber",
            new DateTime(2014, 1, 13, 13, 10, 22),
            new DateTime(2014, 1, 12, 13, 10, 22),
            "documentNumber");

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenADocumentId_WhenADocumentIsRequested_AndTheWCFServiceIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _archiveServiceProxy.Setup(d => d.GetDocument(It.IsAny<AuthenticationData>(), It.IsAny<string>())).Throws<Exception>();

      Action act = () => _documentService.GetDocumentStream(It.IsAny<string>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenADocument_WhenDocumentIsAdded_ItIsSaved()
    {
        _documentService.AddDocument(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>());
      _documentRepository.Verify(s => s.Create(It.IsAny<Document>()), Times.Once());
    }

    [Test]
    public void GivenADocument_WhenDocumentIsAdded_AndDocumentRepositoryCannotCreateDocument_UsingCodeValues_ThenAUnityExceptionIsThrown()
    {
        _documentRepository.Setup(d => d.Create(It.IsAny<Document>())).Throws<Exception>();
        Assert.Throws<UnityException>(() => _documentService.AddDocument(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int?>()));
    }

    [Test]
    public void GivenADocument_WhenDocumentIsAdded_UsingCodeValues_ItIsSaved()
    {
      _docTypeRepository.Setup(d => d.GetDocType(It.IsAny<string>())).Returns(new DocType() { Id = 1 });
      _manCoRepository.Setup(d => d.GetManCo(It.IsAny<string>())).Returns(new ManCo() { Id = 1 });
      subDocTypeRepository.Setup(d => d.GetSubDocType(It.IsAny<string>())).Returns(new SubDocType() { Id = 1 });

      _documentService.AddDocument(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int?>());
      _documentRepository.Verify(s => s.Create(It.IsAny<Document>()), Times.Once());
    }

    [Test]
    public void GivenADocument_WhenDocumentIsAdded_AndDocumentRepositoryCannotCreateDocument_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(d => d.Create(It.IsAny<Document>())).Throws<Exception>();
      Assert.Throws<UnityException>(() => _documentService.AddDocument(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>()));
    }

    [Test]
    public void GivenADocumentId_WhenADocumentIsRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetDocument((It.IsAny<string>()))).Throws<Exception>();

      Action act = () => _documentService.GetDocument(It.IsAny<string>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenADocumentId_WhenADocumentIsRequested_ThenADocumentIsReturned()
    {
      _documentRepository.Setup(a => a.GetDocument(It.IsAny<string>())).Returns(new Document());
      Document doctpye = _documentService.GetDocument(It.IsAny<string>());

      doctpye.Should().NotBeNull();
    }

    [Test]
    public void GivenAGrid_WhenDocumentsAreRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetDocuments((It.IsAny<string>()))).Throws<Exception>();

      Action act = () => _documentService.GetDocuments(It.IsAny<string>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenAGrid_WhenDocumentAreRequested_ThenADocumentDocumentsAreReturned()
    {
      _documentRepository.Setup(a => a.GetDocuments(It.IsAny<string>())).Returns(new List<Document>
                                                                                   {
                                                                                     new Document()
                                                                                   } );
      var documents = _documentService.GetDocuments(It.IsAny<string>());

      documents.Should().NotBeNull().And.HaveCount(1);
    }

    [Test]
    public void GivenAListOfDocumentIds_WhenDocumentsAreRequested_ThenADocumentIsReturned()
    {
      this._documentRepository.Setup(a => a.GetDocuments(It.IsAny<IEnumerable<String>>()))
        .Returns(new List<Document> { new Document() });

      IEnumerable<Document> documents = this._documentService.GetDocuments(It.IsAny<IEnumerable<String>>());

      List<Document> documentList = documents.ToList();

      documentList.Count.Should().Be(1);
      documentList[0].Should().NotBeNull();
    }

    [Test]
    public void GivenAListOfDocumentIds_WhenDocumentsAreRequested_AndTheDatabaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      this._documentRepository.Setup(a => a.GetDocuments(It.IsAny<IEnumerable<String>>())).Throws<Exception>();

      Action act = () => this._documentService.GetDocuments(It.IsAny<IEnumerable<String>>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenAListOfIds_WhenDocumentsAreRequested_ThenADocumentIsReturned()
    {
      this._documentRepository.Setup(a => a.GetDocuments(It.IsAny<IEnumerable<Int32>>()))
        .Returns(new List<Document> { new Document() });

      IEnumerable<Document> documents = this._documentService.GetDocuments(It.IsAny<IEnumerable<Int32>>());

      List<Document> documentList = documents.ToList();

      documentList.Count.Should().Be(1);
      documentList[0].Should().NotBeNull();
    }

    [Test]
    public void GivenAListOfIds_WhenDocumentsAreRequested_AndTheDatabaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      this._documentRepository.Setup(a => a.GetDocuments(It.IsAny<IEnumerable<Int32>>())).Throws<Exception>();

      Action act = () => this._documentService.GetDocuments(It.IsAny<IEnumerable<Int32>>());

      act.ShouldThrow<UnityException>();
    }

        [Test]
    public void GivenAGrid_WhenDocumentsWithApprovalsAreRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetDocuments((It.IsAny<string>()))).Throws<Exception>();

      Action act = () => _documentService.GetDocuments(It.IsAny<string>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenAGrid_WhenDocumentWithApprovalsAreRequested_ThenADocumentDocumentsAreReturned()
    {
      _documentRepository.Setup(a => a.GetDocumentsWithApprovalAndRejectionEntities(It.IsAny<string>())).Returns(new List<Document>
                                                                                   {
                                                                                     new Document()
                                                                                   } );
      var documents = _documentService.GetDocumentsWithApprovalAndRejectionEntities(It.IsAny<string>());

      documents.Should().NotBeNull().And.HaveCount(1);
    }

    [Test]
    public void GivenAManCoId_WhenDocumentsAreRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetDocuments(It.IsAny<int>(), It.IsAny<DateTime>(), It.IsAny<DateTime>())).Throws<Exception>();

      Action act = () => _documentService.GetDocuments(It.IsAny<int>(), It.IsAny<DateTime>(), It.IsAny<DateTime>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenAManCoId_WhenDocumentsAreRequested_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetDocuments(It.IsAny<int>(), It.IsAny<DateTime>(), It.IsAny<DateTime>())).Returns(new List<KpiReportData>
                                                                                   {
                                                                                     new KpiReportData()
                                                                                   });
      var documents = _documentService.GetDocuments(It.IsAny<int>(), It.IsAny<DateTime>(), It.IsAny<DateTime>());

      documents.Should().NotBeNull().And.HaveCount(1);
    }

    [Test]
    public void GivenValidData_WhenApprovedAndNonExportedDocumentsAreRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetApprovedAndNotExported()).Throws<Exception>();

      Action act = () => _documentService.GetApprovedAndNotExported();

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenValidData_WhenApprovedAndNonExportedDocumentsAreRequested_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetApprovedAndNotExported()).Returns(new List<Document>
                                                                                   {
                                                                                     new Document()
                                                                                   });
      var documents = _documentService.GetApprovedAndNotExported();

      documents.Should().NotBeNull().And.HaveCount(1);
    }

    [Test]
    public void GivenValidData_AndAnUnavailableDatabase_WhenIUpdateADocument_ThenAUnityExceptionIsThrown()
    {
      this.houseHoldRepository.Setup(hhr => hhr.Create(It.IsAny<List<HouseHold>>())).Throws<Exception>();

      Action act = () => this._documentService.UpdateAsHouseheld(It.IsAny<Int32>(), It.IsAny<Int32>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenValidData_WhenIUpdateADocument_ThenTheDocumentIsUpdated()
    {
      this._documentService.UpdateAsHouseheld(It.IsAny<Int32>(), It.IsAny<Int32>());
      this.houseHoldRepository.Verify(hhr => hhr.Create(It.IsAny<List<HouseHold>>()), Times.Once);
    }

    [Test]
    public void GivenAGrid_WhenApprovedDocumentsAreRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetApprovedDocuments((It.IsAny<string>()))).Throws<Exception>();

      Action act = () => _documentService.GetApprovedDocuments(It.IsAny<string>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenAGrid_WhenApprovedDocumentAreRequested_ThenADocumentDocumentsAreReturned()
    {
      _documentRepository.Setup(a => a.GetApprovedDocuments(It.IsAny<string>())).Returns(new List<Document>
                                                                                   {
                                                                                     new Document()
                                                                                   });
      var documents = _documentService.GetApprovedDocuments(It.IsAny<string>());

      documents.Should().NotBeNull().And.HaveCount(1);
    }

    [Test]
    public void GivenAGrid_WhenUnApprovedDocumentsAreRequested_AndTheDataBaseIsUnavailable_ThenAUnityExceptionIsThrown()
    {
      _documentRepository.Setup(a => a.GetUnApprovedDocuments((It.IsAny<string>()))).Throws<Exception>();

      Action act = () => _documentService.GetUnApprovedDocuments(It.IsAny<string>());

      act.ShouldThrow<UnityException>();
    }

    [Test]
    public void GivenAGrid_WhenUnApprovedDocumentAreRequested_ThenADocumentDocumentsAreReturned()
    {
      _documentRepository.Setup(a => a.GetUnApprovedDocuments(It.IsAny<string>())).Returns(new List<Document>
                                                                                   {
                                                                                     new Document()
                                                                                   });
      var documents = _documentService.GetUnApprovedDocuments(It.IsAny<string>());

      documents.Should().NotBeNull().And.HaveCount(1);
    }
  }
}
